package com.szh.zx.javacorecorret.chap2.two;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

// 章节2.2.1
// 和CountDownLatch不同的是，cyclicBarrier是可以重置计数的，并且是加法操作
public class CyclicBarrierTest {
	public static void main(String[] args) throws InterruptedException {
		CyclicBarrier cbRef = new CyclicBarrier(5, new Runnable() {
			@Override
			public void run() {
				System.out.println("全都到了 ");
			}
		});
		MyThread[] threadArray = new MyThread[5];
		for (int i = 0; i < threadArray.length; i++) {
			threadArray[i] = new MyThread(cbRef);
		}
		for (int i = 0; i < threadArray.length; i++) {
			threadArray[i].start();
		}
		System.out.println("============== 第二个 为了方便测试，测试下面将上面注释===========");
		CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
			@Override
			public void run() {
				System.out.println("全来了");
			}
		});
		for (int i = 0; i < 4; i++) {
			ThreadA threadA = new ThreadA(cyclicBarrier);
			threadA.start();
			Thread.sleep(20000);
		}
	}

}

class MyThread extends Thread {
	private CyclicBarrier cbRef;

	public MyThread(CyclicBarrier cbRef) {
		this.cbRef = cbRef;
	}

	@Override
	public void run() {
		try {
			Thread.sleep((int) (Math.random() * 1000));
			System.out.println(Thread.currentThread().getName() + " 到了" + System.currentTimeMillis());
			cbRef.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}

}

class ThreadA extends Thread {
	private CyclicBarrier cbRef;

	public ThreadA(CyclicBarrier cbRef) {
		this.cbRef = cbRef;
	}

	@Override
	public void run() {
		try {
			System.out.println(Thread.currentThread().getName() + "begin =" + System.currentTimeMillis() + " 等待凑齐2个继续运行");
			cbRef.await();
			System.out.println(Thread.currentThread().getName() + " end = " + System.currentTimeMillis() + " 已经凑齐了2个继续运行");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
}
